package com.cy.lib.download;

import android.os.AsyncTask;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author CY
 * @date 2015-8-21
 */
public class Download extends AsyncTask<Void, Download.DownloadState, Object> {

    private String mDownloadUrl;
    private File mTargetFile;
    private OnDownloadListener mOnDownloadListener;
    private DownloadInfo mDownloadInfo;
    public static final String EXTRA_DOWNLOAD_URL = "com.cy.lib.download.DownloadService.EXTRA_DOWNLOAD_URL";
    public static final String EXTRA_TARGET_FILE = "com.cy.lib.download.DownloadService.EXTRA_TARGET_FILE";

    public Download(String downloadUrl, File targetFile, OnDownloadListener downloadListener) {
        mDownloadUrl = downloadUrl;
        mTargetFile = targetFile;
        mOnDownloadListener = downloadListener;
        mDownloadInfo = new DownloadInfo();
        mDownloadInfo.setDownloadUrl(mDownloadUrl);
        mDownloadInfo.setTargetFile(mTargetFile);
    }


    @Override
    protected Object doInBackground(Void... params) {
        try {
            download(mDownloadUrl, mTargetFile);
        } catch (IOException e) {
            e.printStackTrace();
            publishProgress(DownloadState.ERROR);
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Download.DownloadState... values) {
        super.onProgressUpdate(values);
        DownloadState state = values[0];
        if (mOnDownloadListener != null) {
            mOnDownloadListener.downloadState(state, mDownloadInfo);
        }
    }

    public void download(String downloadUrl, File targetFile) throws IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(downloadUrl).openConnection();
        connection.setDoInput(true);
        connection.connect();
        long contentLength = connection.getContentLength();
        long currentProgress = 0;

        mDownloadInfo.setContentLength(contentLength);
        mDownloadInfo.setCurrentProgress(currentProgress);
        publishProgress(DownloadState.START);

        InputStream is = connection.getInputStream();
        if (!targetFile.exists()) {
            if (!targetFile.getParentFile().exists()) {
                targetFile.getParentFile().mkdirs();
            }
            targetFile.createNewFile();
        }
        FileOutputStream fos = new FileOutputStream(targetFile);
        byte data[] = new byte[1024];
        int index = -1;
        while ((index = is.read(data)) != -1) {
            mDownloadInfo.setCurrentProgress(currentProgress);
            publishProgress(DownloadState.PROGRESS);
            fos.write(data, 0, index);
            currentProgress += index;
        }
        mDownloadInfo.setCurrentProgress(currentProgress);
        publishProgress(DownloadState.PROGRESS);
        publishProgress(DownloadState.COMPLETE);
        fos.flush();
        fos.close();
        is.close();
    }

    /**
     * @author CY
     */
    public interface OnDownloadListener {

        void downloadState(DownloadState state, DownloadInfo info);
    }

    public enum DownloadState {

        START, PROGRESS, COMPLETE, ERROR
    }

    //        下载完成广播
    public static final String BROAST_DOWNLOAD_COMPLETE = "com.cy.lib.download.DownloadService.BROAST_DOWNLOAD_COMPLETE";

    public static class DownloadInfo {

        private String downloadUrl;
        private File targetFile;
        private long contentLength;
        private long currentProgress;

        private static DownloadInfo info;

        protected DownloadInfo() {

        }

        public synchronized static DownloadInfo obtain() {
            if (info == null) {
                info = new DownloadInfo();
            }
            return info;
        }

        public String getDownloadUrl() {
            return downloadUrl;
        }

        public void setDownloadUrl(String downloadUrl) {
            this.downloadUrl = downloadUrl;
        }

        public File getTargetFile() {
            return targetFile;
        }

        public void setTargetFile(File targetFile) {
            this.targetFile = targetFile;
        }

        public long getContentLength() {
            return contentLength;
        }

        public void setContentLength(long contentLength) {
            this.contentLength = contentLength;
        }

        public long getCurrentProgress() {
            return currentProgress;
        }

        public void setCurrentProgress(long currentProgress) {
            this.currentProgress = currentProgress;
        }

        public static DownloadInfo getInfo() {
            return info;
        }

        public static void setInfo(DownloadInfo info) {
            DownloadInfo.info = info;
        }
    }
}